//
//  XLHttpNetworking.m
//  WebSocketTest
//
//  Created by tanqilong on 16/8/11.
//  Copyright © 2016年 tanqilong. All rights reserved.
//

#import "XLHttpNetworking.h"
#import <AFNetworking/AFNetworking.h>
#import "XLDataBaseManager.h"
#import "XLNetWorkingHandle.h"

@interface XLHttpNetworking ()
{
    AFHTTPSessionManager * _netManager;
    NSURLSessionDataTask * _dataTask;
}
@property (nonatomic,strong) XLDataBaseManager * dataBaseManager; //本地存储使用
@property (nonatomic,assign) XLRequestMethod requestMethod; //请求方式
@end

@implementation XLHttpNetworking

-(id)initWithUrl:(NSString *)url Parameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    self = [super init];
    if (self) {
        //获取请求的3中状态
        self.sucBlock = sucBlock;
        self.errorBlock = errorBlock;
        self.cancelBlock = cancelBlock;
        self.requestUrl = url;
        if ([self getRequestMethod] != 0) {
            self.requestMethod = [self getRequestMethod];
        }
        else {
            self.requestMethod = XLRequestMethodGet;
        }
        [self netWithParameters:dic IndicatorView:view LoadingFinished:sucBlock CancelLoading:cancelBlock LoadingError:errorBlock];
    }
    return self;
}

-(id)initWithUrl:(NSString *)url requestMethod:(XLRequestMethod)requestMethod Parameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    self = [super init];
    if (self) {
        //获取请求的3中状态
        self.sucBlock = sucBlock;
        self.errorBlock = errorBlock;
        self.cancelBlock = cancelBlock;
        self.requestUrl = url;
        self.requestMethod = requestMethod;
        [self netWithParameters:dic IndicatorView:view LoadingFinished:sucBlock CancelLoading:cancelBlock LoadingError:errorBlock];
    }
    return self;
}

-(id)initWithParameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    self = [super init];
    if (self) {
        //获取请求的3中状态
        self.sucBlock = sucBlock;
        self.errorBlock = errorBlock;
        self.cancelBlock = cancelBlock;
        if (self.requestUrl == nil) {
            self.requestUrl = [self getRequestUrl];
        }
        if ([self getRequestMethod] != 0) {
            self.requestMethod = [self getRequestMethod];
        }
        else {
            self.requestMethod = XLRequestMethodGet;
        }
        [self netWithParameters:dic IndicatorView:view LoadingFinished:sucBlock CancelLoading:cancelBlock LoadingError:errorBlock];
    }
    return self;
}

-(void)netWithParameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    _netManager = [AFHTTPSessionManager manager];
    //很重要 不设置这句话 带参数的接口无法获取到
    _netManager.responseSerializer = [AFCompoundResponseSerializer serializer];
    //网络加载是的缓冲处理
    [self loadMaskAcivityView:view];
    
    __weak typeof(self) weakSelf = self;
    //如果地址为空跑出异常
    NSAssert(self.requestUrl != nil, @"加载网址为空，不能加载");
    [[XLNetWorkingHandle shareInstance]pushNetWokingObj:self];
    //判断是post还是get请求数据
    switch (self.requestMethod) {
        case XLRequestMethodGet:{
            //get请求
            _dataTask = [_netManager GET:self.requestUrl parameters:dic progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                [weakSelf sucBlockDo:responseObject];
                [weakSelf logMessage:responseObject];
                [[XLNetWorkingHandle shareInstance]popNetWokingObj:weakSelf];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [weakSelf errorBlockDo:error];
                [weakSelf logMessage:error];
                [[XLNetWorkingHandle shareInstance]popNetWokingObj:weakSelf];
            }];
        }
            break;
        case XLRequestMethodPost:{
            //post请求
            _dataTask = [_netManager POST:self.requestUrl parameters:dic progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                //请求成功后讲传递给自己的子类调用
                [weakSelf sucBlockDo:responseObject];
                [weakSelf logMessage:responseObject];
                [[XLNetWorkingHandle shareInstance]popNetWokingObj:weakSelf];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [weakSelf errorBlockDo:error];
                [weakSelf logMessage:error];
                [[XLNetWorkingHandle shareInstance]popNetWokingObj:weakSelf];
            }];
            
        }
        default:
            break;
    }
}

//打印参数和接口信息
-(void)logMessage:(id)result {
    //data转json
    if (self.islogMessage) {
        NSLog(@"接口信息%@\n%@",_dataTask.currentRequest.URL.absoluteString,self.originResult);
    }
}

//取消请求
-(void)cancelRequest
{
    if (self.cancelBlock) {
        self.cancelBlock();
    }
    [_dataTask cancel];
    [_netManager.operationQueue cancelAllOperations];
    [self loadFinished];
}

//获取请求方式 默认为get
- (XLRequestMethod)getRequestMethod
{
    return 0;
}


#pragma mark -- 网络加载与本地交互处理

-(id)initNativeWithUrl:(NSString *)url Parameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    self = [super init];
    if (self) {
        //获取请求的3中状态
        self.sucBlock = sucBlock;
        self.errorBlock = errorBlock;
        self.cancelBlock = cancelBlock;
        self.requestUrl = url;
        [self netNativeWithParameters:dic IndicatorView:view IsMustLoadingFromNet:NO];
    }
    return self;
}

//如果本地有则用本地的否则发起网路请求
-(id)initNativeWithParameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    self = [super init];
    if (self) {
        //获取请求的3中状态
        self.sucBlock = sucBlock;
        self.errorBlock = errorBlock;
        self.cancelBlock = cancelBlock;
        if (self.requestUrl == nil) {
            self.requestUrl = [self getRequestUrl];
        }
        [self netNativeWithParameters:dic IndicatorView:view IsMustLoadingFromNet:NO];
    }
    return self;
}
//如果本地有则先用本地的然后再次发起网络请求一次更新
-(id)initNativeAndNetWithParameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view LoadingFinished:(sucBlock)sucBlock CancelLoading:(cancelBlock)cancelBlock LoadingError:(errorBlock)errorBlock {
    self = [super init];
    if (self) {
        //获取请求的3中状态
        self.sucBlock = sucBlock;
        self.errorBlock = errorBlock;
        self.cancelBlock = cancelBlock;
        if (self.requestUrl == nil) {
            self.requestUrl = [self getRequestUrl];
        }
        [self netNativeWithParameters:dic IndicatorView:view IsMustLoadingFromNet:YES];
    }
    return self;
}

-(void)netNativeWithParameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view IsMustLoadingFromNet:(BOOL)isMust{
    //use url to the key for store and restore from database
    NSString * requestStr = [[[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:self.requestUrl parameters:dic error:nil] URL]absoluteString];
    self.dataBaseManager = [[XLDataBaseManager alloc]initWithDataBaseUrl:nil];
    __weak typeof (self) ws = self;
    //先从本地加载
    [self.dataBaseManager selectValueDataByNetTableWithUrlStr:requestStr CompleteBlock:^(NSString *data) {
        if (data) {
            [ws sucBlockDo:data];
            if (isMust) {
                //加载本地后再加载一次网络
                [ws getMessageFromNetWithParameters:dic IndicatorView:view Url:requestStr];
            }
        }
        else {
            //如果没有数据则发起网络请求
            [ws getMessageFromNetWithParameters:dic IndicatorView:view Url:requestStr];
        }
    }];
}
//网络获取数据且存储到本地
-(void)getMessageFromNetWithParameters:(NSMutableDictionary *)dic IndicatorView:(UIView *)view Url:(NSString *)url{
    _netManager = [AFHTTPSessionManager manager];
    //很重要 不设置这句话 带参数的接口无法获取到
    _netManager.responseSerializer = [AFCompoundResponseSerializer serializer];
    //网络加载是的缓冲处理
    [self loadMaskAcivityView:view];
    
    __weak typeof(self) weakSelf = self;
    //如果地址为空跑出异常
    NSAssert(self.requestUrl != nil, @"加载网址为空，不能加载");
    //判断是post还是get请求数据
    if (self.requestMethod == 0 && [self requestMethod] != 0) {
        self.requestMethod = [self requestMethod];
    }
    else {
        self.requestMethod = XLRequestMethodGet;
    }
    switch (self.requestMethod) {
        case XLRequestMethodGet:{
            //get请求
            _dataTask = [_netManager GET:self.requestUrl parameters:dic progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                if ([responseObject isKindOfClass:[NSData class]]) {
                    //存储网络加载好的数据
                    //                    NSString * dataStr = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
                    NSString * dataStr = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
                    [weakSelf.dataBaseManager insertDataToNetTableWithUrlStr:url Value:dataStr CompleteBlock:nil];
                }
                [weakSelf sucBlockDo:responseObject];
                [weakSelf logMessage:responseObject];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [weakSelf errorBlockDo:error];
                [weakSelf logMessage:error];
            }];
        }
            break;
        case XLRequestMethodPost:{
            //post请求
            _dataTask = [_netManager POST:self.requestUrl parameters:dic progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                if ([responseObject isKindOfClass:[NSData class]]) {
                    //存储网络加载好的数据
                    //                    NSString * dataStr = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers | NSJSONReadingMutableLeaves error:nil];
                    NSString * dataStr = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
                    [weakSelf.dataBaseManager insertDataToNetTableWithUrlStr:url Value:dataStr CompleteBlock:nil];
                }
                //请求成功后讲传递给自己的子类调用
                [weakSelf sucBlockDo:responseObject];
                [weakSelf logMessage:responseObject];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [weakSelf errorBlockDo:error];
                [weakSelf logMessage:error];
            }];
        }
        default:
            break;
    }
}

-(void)dealloc {
    [_netManager.operationQueue cancelAllOperations];
}

@end
